package com.chinaunicom.emergency.util;

import org.apache.commons.lang3.StringUtils;

import javax.persistence.criteria.CriteriaBuilder;
import javax.persistence.criteria.Predicate;
import javax.persistence.criteria.Root;
import java.util.List;
import java.util.Map;

/**
 * @author liliang
 * @date 2019-12-13
 * 数据查询条件拼接工具类
 */
public class JPAUtil {

    public static void equal(List<Predicate> predicates,CriteriaBuilder cb, Root<?> root, String colmun, Map para) {
        equal(predicates,cb,root,colmun,para,colmun);
    }

    public static void notEqual(List<Predicate> predicates,CriteriaBuilder cb, Root<?> root, String colmun, Map para) {
        notEqual(predicates,cb,root,colmun,para,colmun);
    }

    public static void equal(List<Predicate> predicates,CriteriaBuilder cb, Root<?> root, String colmun, Map para,String paraKey) {
        if(!checkPara(paraKey,para)){
            return;
        }
        predicates.add(cb.equal(root.get(colmun), para.get(paraKey)));
    }
    public static void notEqual(List<Predicate> predicates,CriteriaBuilder cb, Root<?> root, String colmun, Map para,String paraKey) {
        if(!checkPara(paraKey,para)){
            return;
        }
        predicates.add(cb.notEqual(root.get(colmun), para.get(paraKey)));
    }
    public static void likeLeft(List<Predicate> predicates,CriteriaBuilder cb, Root<?> root, String colmun, Map para) {
        likeLeft(predicates,cb,root,colmun,para,colmun);
    }
    public static void likeLeft(List<Predicate> predicates,CriteriaBuilder cb, Root<?> root, String colmun, Map para,String paraKey) {
        if(!checkPara(paraKey,para)){
            return;
        }
        predicates.add(cb.like(root.get(colmun), "%"+para.get(paraKey)));
    }

    public static void likeRight(List<Predicate> predicates,CriteriaBuilder cb, Root<?> root, String colmun, Map para) {
        likeRight(predicates,cb,root,colmun,para,colmun);
    }

    public static void likeRight(List<Predicate> predicates,CriteriaBuilder cb, Root<?> root, String colmun, Map para,String paraKey) {
        if(!checkPara(paraKey,para)){
            return;
        }
        predicates.add(cb.like(root.get(colmun), para.get(paraKey) + "%"));
    }

    public static void like(List<Predicate> predicates,CriteriaBuilder cb, Root<?> root, String colmun, Map para) {
        like(predicates,cb,root,colmun,para,colmun);
    }

    public static void like(List<Predicate> predicates,CriteriaBuilder cb, Root<?> root, String colmun, Map para,String paraKey) {
        if(!checkPara(paraKey,para)){
            return;
        }
        predicates.add(cb.like(root.get(colmun), "%" + para.get(paraKey) + "%"));
    }

    public static void greaterThanOrEqualToDate(List<Predicate> predicates,CriteriaBuilder cb, Root<?> root, String colmun, Map para) {
        greaterThanOrEqualToDate(predicates,cb,root,colmun,para,colmun);
    }

    public static void greaterThanOrEqualToDate(List<Predicate> predicates,CriteriaBuilder cb, Root<?> root, String colmun, Map para,String paraKey) {
        if(!checkPara(paraKey,para)){
            return;
        }
        predicates.add(cb.greaterThanOrEqualTo(root.get(colmun), DateUtil.stringToDate(para.get(paraKey) + " 00:00:00")));
    }

    public static void lessThanOrEqualToDate(List<Predicate> predicates,CriteriaBuilder cb, Root<?> root, String colmun, Map para) {
        lessThanOrEqualToDate(predicates,cb,root,colmun,para,colmun);
    }

    public static void lessThanOrEqualToDate(List<Predicate> predicates,CriteriaBuilder cb, Root<?> root, String colmun, Map para,String paraKey) {
        if(!checkPara(paraKey,para)){
            return;
        }
        predicates.add(cb.lessThanOrEqualTo(root.get(colmun), DateUtil.stringToDate(para.get(paraKey) + " 23:59:59")));
    }

    public static void isNull(List<Predicate> predicates,CriteriaBuilder cb, Root<?> root, String colmun) {
        predicates.add(cb.isNull(root.get(colmun)));
    }
    public static void isNotNull(List<Predicate> predicates,CriteriaBuilder cb, Root<?> root, String colmun) {
        predicates.add(cb.isNotNull(root.get(colmun)));
    }

    public static void between(List<Predicate> predicates,CriteriaBuilder cb, Root<?> root, String colmun, Integer min, Integer max) {
        predicates.add(cb.between(root.get(colmun), min, max));
    }

    public static void in(List<Predicate> predicates,CriteriaBuilder cb, Root<?> root, String colmun, Map para,String paraKey) {
        if(!checkPara(paraKey,para)){
            return;
        }
        List<?> list = (List<?>) para.get(paraKey);
        CriteriaBuilder.In<Object> in = cb.in(root.get(colmun));
        for(int i = 0; i < list.size(); i++) {
            in.value(list.get(i));
        }
        predicates.add(in);
    }

    public static void notIn(List<Predicate> predicates,CriteriaBuilder cb, Root<?> root, String colmun, Map para,String paraKey) {
        if(!checkPara(paraKey,para)){
            return;
        }
        List<?> list = (List<?>) para.get(paraKey);
        CriteriaBuilder.In<Object> in = cb.in(root.get(colmun));
        for(int i = 0; i < list.size(); i++) {
            in.value(list.get(i));
        }
        predicates.add(cb.not(in));
    }

    private static boolean checkPara(String paraKey,Map para){
        if (para.get(paraKey) != null) {
            if (para.get(paraKey) instanceof String) {
                if (StringUtils.isBlank((String) para.get(paraKey))) {
                    return false;
                }
            } else if (para.get(paraKey) instanceof List) {
                if (((List) para.get(paraKey)).isEmpty()) {
                    return false;
                }
            }
        } else {
            return false;
        }
        return true;
    }

    public static void lessToDate(List<Predicate> predicates,CriteriaBuilder cb, Root<?> root, String colmun, Map para,String paraKey) {
        if(!checkPara(paraKey,para)){
            return;
        }
        predicates.add(cb.lessThanOrEqualTo(root.get(colmun), DateUtil.stringToDate(para.get(paraKey)+"")));
    }

    public static void greaterToDate(List<Predicate> predicates,CriteriaBuilder cb, Root<?> root, String colmun, Map para,String paraKey) {
        if(!checkPara(paraKey,para)){
            return;
        }
        predicates.add(cb.greaterThanOrEqualTo(root.get(colmun), DateUtil.stringToDate(para.get(paraKey) + "")));
    }
}
